package com.jplus.rpc.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

import com.jplus.rpc.bean.RpcRequest;
import com.jplus.rpc.bean.RpcResponse;
import com.jplus.rpc.bean.Service;
import com.jplus.rpc.bean.ZNode;
import com.jplus.rpc.impl.handler.ServiceType;
import com.jplus.rpc.impl.iface.IAgreement;
import com.jplus.rpc.impl.iface.IWatcher;

/**
 * 实现工厂
 * 
 * @author Yuanqy
 *
 */
public class AgreementFactory {

	public synchronized static boolean startServer(Map<String, Service> handler, Set<ServiceType> suport) throws Exception {
		for (ServiceType st : suport) {
			RpcProcess(getInstance(st.getCls()), handler);
		}
		return true;
	}

	public synchronized static RpcResponse startClient(RpcRequest request, ZNode serNode) throws Exception {
		return getInstance(serNode.getServiceType().getCls()).opClient(request, serNode);
	}

	/**
	 * 【启动服务】同步方法
	 */
	private static boolean RpcProcess(IAgreement agree, Map<String, Service> handler) throws Exception {
		final CountDownLatch latch = new CountDownLatch(1);
		agree.opServer(new IWatcher() {
			@Override
			public void process(boolean bo) throws Exception {
				if (bo)
					latch.countDown();
				else
					throw new Exception("RPC发布失败");
			}
		}, handler);
		latch.await();
		return true;
	}

	private static Map<Class<?>, Object> mapCache = new HashMap<Class<?>, Object>();

	private static <T extends IAgreement> T getInstance(Class<T> clazz) throws InstantiationException, IllegalAccessException {
		@SuppressWarnings("unchecked")
		T t = (T) mapCache.get(clazz);
		if (t == null) {
			mapCache.put(clazz, clazz.newInstance());
			return getInstance(clazz);
		}
		return t;
	}
}
